import jwt from 'jsonwebtoken';
import env from '../../env';
import { UserId } from '../user/model';
import shordId from 'short-uuid';
import dayjs from 'dayjs';

export interface Payload {
  /**
   * subject: userId
   */
  sub: UserId;
  /**
   * jwt id: session id
   */
  jti: string;
  /**
   * expiration time: seconds
   */
  exp: number;
}

export function sign(userId: UserId) {
  const payload: Payload = {
    sub: userId,
    jti: shordId.generate(),
    exp: dayjs().add(1, 'month').unix(),
  };
  return jwt.sign(payload, env.SERVER.JWT_SECRET);
}

export async function verify(token: string): Promise<Payload> {
  return await new Promise((resolve, reject) =>
    jwt.verify(token, env.SERVER.JWT_SECRET, (err, decode) => {
      if (err) return reject(err);
      else if (!decode) return reject(new Error('jwt decode empty'));
      else {
        resolve({
          sub: +decode.sub!,
          jti: decode.jti!,
          exp: decode.exp!,
        });
      }
    })
  );
}
